package print;

import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.util.ArrayList;
import java.util.List;

import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.swing.JTable;
import javax.swing.SwingUtilities;

import jp.gr.java_conf.tame.swing.table.AttributiveCellTableModel;
import jp.gr.java_conf.tame.swing.table.CellSpan;
import jp.gr.java_conf.tame.swing.table.MultiSpanCellTable;
import table.models.RankingPrintTableModel;
import table.models.RankingTable;
import table.models.TestFrame;
import core.GuiComponentLabels;

public class Printer {

	public Printer(JTable toPrint, String subTitle) {
		try {
			// toPrint.print(JTable.PrintMode.FIT_WIDTH);
			this.printJTable(toPrint, subTitle);
		} catch (PrinterException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public Printer(List < RankingTable > toPrint, String subTitle) {
		try {
			// toPrint.print(JTable.PrintMode.FIT_WIDTH);
			this.printJTable(toPrint, subTitle);
		} catch (PrinterException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void printJTable(JTable table, String subTitle) throws PrinterException {
		// possibly prepare the table for printing here first
		// wrap in a try/finally so table can be restored even if something
		// fails
		try {
			// fetch the printable
			Printable printable = new TablePrinter(table, subTitle);
			PrinterJob job = PrinterJob.getPrinterJob();// fetch a PrinterJob
			job.setPrintable(printable);// set the Printable on the PrinterJob
			// create an attribute set to store attributes from the print dialog
			PrintRequestAttributeSet attr = new HashPrintRequestAttributeSet();
			// display a print dialog and record whether or not the user cancels
			// it
			boolean printAccepted = job.printDialog(attr);
			if (printAccepted) {// if the user didn't cancel the dialog
				job.print(attr);// do the printing
			}
		} finally {
			// possibly restore the original table state here
		}
	}

	private void printJTable(List < RankingTable > tableList, String subTitle) throws PrinterException {
		final RankingTable tmpTable = this.buildPrintableTable(tableList);

		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				JTable toPrint = tmpTable.toJTable();
				System.out.println(toPrint.getValueAt(0, 0));
				MultiSpanCellTable spanTable = tmpTable.toCellSpanTable();
				System.out.println(spanTable.getValueAt(0, 0));
				AttributiveCellTableModel model = (AttributiveCellTableModel) spanTable.getModel();
				CellSpan cellAtt = (CellSpan) model.getCellAttribute();
				cellAtt.combine(new int [] { 0 }, new int [] { 0, 1 });
				// model.setValueAt("1", 0, 0);

				TestFrame inst = new TestFrame(spanTable);
				inst.setLocationRelativeTo(null);
				inst.setVisible(true);
			}
		});
	}

	private RankingTable buildPrintableTable(List < RankingTable > tableList) {
		RankingTable toReturn = new RankingTable();
		RankingPrintTableModel model = new RankingPrintTableModel();

		// add rowdata
		ArrayList < String > columnNames = new ArrayList < String >();
		columnNames.add(GuiComponentLabels.RANK);
		columnNames.add(GuiComponentLabels.NAME);
		columnNames.add(GuiComponentLabels.CLUB);
		model.setColumnNames(columnNames);
		for (RankingTable toAdd : tableList) {
			// add eventually missing columns to new table
			if (toAdd.getColumnCount() > model.getColumnCount()) {
				for (int i = 0; i < toAdd.getColumnCount(); i++) {
					if (model.getColumnCount() == i) {
						model.insertColumn(i, toAdd.getColumnName(i));
					}
					if (!toAdd.getColumnName(i).equals(model.getColumnName(i))) {
						model.insertColumn(i, toAdd.getColumnName(i));
					}
				}
			}

			// add description
			ArrayList < Object > combination = new ArrayList < Object >();
			combination.add(toAdd.getTitle());
			model.addRow();
			model.addRow(combination);
			model.addRow();

			// add values
			model.addRow(model.getColumnNamesAsObjects());
			for (int i = 0; i < toAdd.getRowCount(); i++) {
				ArrayList < Object > rowData = new ArrayList < Object >();
				for (int j = 0; j < toAdd.getColumnCount(); j++) {
					if (toAdd.getColumnName(j).equals(model.getColumnName(j))) {
						rowData.add(toAdd.getValueAt(i, j));
					} else {
						rowData.add(new String(""));
					}
				}
				model.addRow(rowData);
			}
		}

		toReturn.setModel(model);
		return toReturn;
	}
}
